home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / uucp106d / part08 < prev    next >
Encoding:
Text File  |  1990-06-28  |  43.3 KB  |  2,042 lines

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i186: UUCP 1.06D - UNIX compatible uucp/news/mail system, Part08/12
  5. Message-ID: <12977@xanth.cs.odu.edu>
  6. Date: 28 Jun 90 12:23:12 GMT
  7. Sender: news@cs.odu.edu
  8. Reply-To: Matt Dillon <@uunet.uu.net:overload!dillon>
  9. Lines: 2028
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon>
  15. Posting-number: Volume 90, Issue 186
  16. Archive-name: unix/uucp-1.06d/part08
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 8 (of 12)."
  25. # Contents:  uucp2/src/getty/getty.c uucp2/src/uucico/gio.c
  26. # Wrapped by tadguy@xanth on Thu Jun 28 08:21:31 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'uucp2/src/getty/getty.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'uucp2/src/getty/getty.c'\"
  30. else
  31. echo shar: Extracting \"'uucp2/src/getty/getty.c'\" \(20766 characters\)
  32. sed "s/^X//" >'uucp2/src/getty/getty.c' <<'END_OF_FILE'
  33. X
  34. X/*
  35. X *  GETTY.C
  36. X *
  37. X *  $Header: Beta:src/uucp/src/getty/RCS/getty.c,v 1.1 90/02/02 12:13:30 dillon Exp Locker: dillon $
  38. X *
  39. X *  (C)Copyright 1989, Matthew Dillon, All Rights Reserved
  40. X *
  41. X *  Uses:
  42. X *    GETTY:PASSWD
  43. X *    GETTY:LOGFILE
  44. X *    GETTY:Getty-Header
  45. X *
  46. X *  GETTY   <options>    <modem-commands>
  47. X *
  48. X *    -Sdevicenam Tells GETTY which serial.device to use, default
  49. X *            serial.device
  50. X *
  51. X *    -Uunitnum   Tells GETTY which unit number to use, default 0
  52. X *
  53. X *    -A        Always talk to the modem at the first baud
  54. X *            rate in the -B list and ignore the baud rate
  55. X *            in the CONNECT message.
  56. X *
  57. X *    -7        use SERF_7WIRE while online.
  58. X *
  59. X *    -Bn        Set baud rate.  If specified multiple times the
  60. X *            first one is the default and remaining ones
  61. X *            switched to when a BREAK is received after a
  62. X *            connect.  Also determines how CONNECT messages
  63. X *            are interpreted.  A CONNECT with no number uses
  64. X *            the first -B entry while CONNECTs with numbers
  65. X *            use those numbers regardless of any -B entries.
  66. X *
  67. X *    -Mc        Set modem type:
  68. X *            c = m    = multimodem
  69. X *                h    = hays
  70. X *                d    = dumb (no AT or +++ cmds are ever sent),
  71. X *                  normally used with only one specified
  72. X *                  baud rate.
  73. X *
  74. X *    -m1        Turn on the modem speaker during dialing/connect
  75. X *            (default is -m0)
  76. X *
  77. X *    -h0        Ignore CD (carrier detect), default is to use
  78. X *            carrier detect.
  79. X *
  80. X *    -c0        Ignore CONNECT message (i.e. you are not connected
  81. X *            to a modem, usually combined with -h0).  Default is
  82. X *            to expect a CONNECT message.
  83. X *
  84. X *    -d0        do not use DTR to drop connection.    Default is
  85. X *            to drop DTR to drop a connection.  If this option
  86. X *            is chosen the +++ and ATH0 sequence will be used
  87. X *            to drop a connection.
  88. X *
  89. X *    -xn        Set debug level.  Also causes log output to go
  90. X *            to stdout instead of GETTY:LOGFILE
  91. X *
  92. X *    -0        QUIT - Kills any running getty for the specified
  93. X *            port.
  94. X *
  95. X *    Any fields specified without a '-' are considered modem commands
  96. X *    used to initialize/reinitialize the modem.  Up to 16 fields may
  97. X *    be specified (each is sent to the modem in 1 second intervals)
  98. X */
  99. X
  100. X#include <exec/types.h>
  101. X#include <exec/lists.h>
  102. X#include <exec/devices.h>
  103. X#include <devices/timer.h>
  104. X#include <devices/serial.h>
  105. X#include <libraries/dos.h>
  106. X#include <libraries/dosextens.h>
  107. X#include <hardware/cia.h>
  108. X#include <stdio.h>
  109. X#include <stdlib.h>
  110. X#include "protos.h"
  111. X#include <pwd.h>
  112. X#include "version.h"
  113. X
  114. X#include "log.h"
  115. X
  116. XIDENT(".02");
  117. X
  118. X#ifndef IO_STATF_READBREAK
  119. X#define IO_STATF_READBREAK (IOSTF_READBREAK<<8)
  120. X#endif
  121. X
  122. X#define arysize(ary)    (sizeof(ary)/sizeof((ary)[0]))
  123. X
  124. X#define ST_WAITCD    0
  125. X#define ST_CONNECT    1
  126. X#define ST_LOGIN    2
  127. X#define ST_PASSWD    3
  128. X#define ST_RUN        4
  129. X
  130. Xtypedef struct IORequest    IOR;
  131. Xtypedef struct timerequest  IOT;
  132. Xtypedef struct IOExtSer     IOSER;
  133. Xtypedef struct MsgPort        PORT;
  134. Xtypedef struct List        LIST;
  135. Xtypedef struct Node        NODE;
  136. Xtypedef struct Message        MSG;
  137. Xtypedef void (*FPTR)();
  138. X
  139. Xtypedef struct GMsg {
  140. X    struct Message  Msg;
  141. X    short   Cmd;
  142. X    long    Data1;
  143. X    void    *Data2;
  144. X} GMsg;
  145. X
  146. Xextern struct ProcID *RunPasswdEntry();
  147. X
  148. Xchar    *CopyRight = "(c)Copyright 1989, Matthew Dillon, All Rights Reserved\r\n";
  149. Xchar    *ComPortName;
  150. X
  151. Xchar    *DeviceName = "serial.device";
  152. Xlong    DeviceUnit  = 0;
  153. Xlong    NullFH;
  154. Xchar    SpeakerLevel    = 0;
  155. Xchar    AnswerRing    = 2;    /*  default, answer on second ring */
  156. Xchar    SpeakerOpt    = 0;
  157. Xchar    IgnoreCD    = 0;
  158. Xchar    IgnoreConnect    = 0;
  159. Xchar    IgnoreDTR    = 0;
  160. Xchar    BaudAdjust    = 0;
  161. Xchar    DropOnExit    = 1;
  162. Xchar    ModemType    = 'h';
  163. Xchar    ZeroOption    = 0;
  164. Xchar    Wire7        = 0;        /*  use 7 wire while online */
  165. Xchar    Locked        = 0;        /*  serial port is lcked    */
  166. Xlong    Bauds[16] = { 9600 };        /*  up 16 baud rates        */
  167. Xchar    *AtFields[16];
  168. X
  169. XPORT    *ComPort;
  170. XPORT    *IoSink;    /*  Sink for IO reqs.    */
  171. Xlong    IoSinkMask;
  172. Xlong    ComPortMask;
  173. X
  174. XIOT    Iot;        /*  check-carrier    */
  175. XIOSER    Iosr;        /*  serial read-req    */
  176. XIOSER    Iosw;        /*  serial write-req    */
  177. X
  178. Xchar    IotIP;        /*  Iot0 in progress    */
  179. Xchar    IosrIP;
  180. X
  181. Xchar    ScrBuf[256];
  182. Xchar    ConnectBuf[64];
  183. Xchar    LoginBuf[32];
  184. Xchar    PasswdBuf[32];
  185. Xchar    RxBuf[32];
  186. Xchar    HaveConnectMsg;
  187. Xchar    HaveLogin;
  188. Xchar    HavePasswd;
  189. X
  190. Xshort    State;
  191. Xshort    Index;
  192. Xshort    BIndex;
  193. X
  194. Xshort CountDown;
  195. Xshort GotOffPort;
  196. X
  197. Xvoid    SerPuts();
  198. Xvoid    Set7Wire();
  199. Xvoid    xexit();
  200. Xvoid    Disconnect();
  201. Xvoid    ClearRecv();
  202. Xvoid    InitModem();
  203. Xvoid    SetParams();
  204. Xvoid    DoOptions();
  205. Xvoid    SerialOff();
  206. Xvoid    InterceptDeviceVector();
  207. Xvoid    RestoreDeviceVector();
  208. X
  209. Xbrk()
  210. X{
  211. X    return(0);
  212. X}
  213. X
  214. Xmain(ac, av)
  215. Xchar *av[];
  216. X{
  217. X    extern int IAmGetty;
  218. X    char termCr = 1;
  219. X    char termLf = 1;
  220. X
  221. X    IAmGetty = 1;    /*  for LockSerialPort()/UnLockSerialPort()   */
  222. X
  223. X    puts(CopyRight);
  224. X    fflush(stdout);
  225. X    onbreak(brk);
  226. X
  227. X    LogProgram = "Getty";
  228. X    LogWho = LoginBuf;
  229. X    LogFile = "Getty:LOGFILE";
  230. X    PasswdFile = "Getty:Passwd";
  231. X
  232. X    DoOptions(ac, av);
  233. X
  234. X    IoSink = CreatePort(NULL, 0);
  235. X    IoSinkMask = 1 << IoSink->mp_SigBit;
  236. X
  237. X    ComPortName = malloc(strlen(DeviceName) + 20);
  238. X    sprintf(ComPortName, "Getty.%s.%ld", DeviceName, DeviceUnit);
  239. X
  240. X    Forbid();
  241. X    if (ComPort = FindPort(ComPortName)) {
  242. X    GMsg msg;
  243. X    msg.Cmd = 'O';
  244. X    msg.Data1 = ac;
  245. X    msg.Data2 = (void *)av;
  246. X    msg.Msg.mn_ReplyPort = IoSink;
  247. X    PutMsg(ComPort, &msg.Msg);
  248. X    WaitPort(IoSink);
  249. X    Remove(&msg.Msg.mn_Node);
  250. X    Permit();
  251. X    puts("Options updated");
  252. X    xexit(0);
  253. X    }
  254. X    ComPort = CreatePort(ComPortName, 0L);
  255. X    Permit();
  256. X
  257. X    ComPortMask = 1L << ComPort->mp_SigBit;
  258. X
  259. X    NullFH = Open("NULL:", 1006);
  260. X    if (NullFH == NULL) {
  261. X    ulog(-1, "GETTY REQUIRES NULL: HANDLER!");
  262. X    puts("Requires NULL: handler!");
  263. X    xexit(1);
  264. X    }
  265. X    if (LogToStdout == 0) {
  266. X    freopen("NULL:", "r", stdin);
  267. X    freopen("NULL:", "w", stdout);
  268. X    freopen("NULL:", "w", stderr);
  269. X    }
  270. X
  271. X
  272. X    /*
  273. X     *    Timer Device
  274. X     */
  275. X
  276. X    Iot.tr_node.io_Message.mn_ReplyPort = IoSink;
  277. X    if (OpenDevice("timer.device", UNIT_VBLANK, &Iot, 0L)) {
  278. X    Iot.tr_node.io_Device = NULL;
  279. X    xexit(20);
  280. X    }
  281. X    Iot.tr_node.io_Command = TR_ADDREQUEST;
  282. X
  283. X    /*
  284. X     *    SERIAL.DEVICE
  285. X     */
  286. X
  287. X    Iosr.IOSer.io_Message.mn_ReplyPort = IoSink;
  288. X    Iosr.io_SerFlags = SERF_XDISABLED | SERF_7WIRE | SERF_RAD_BOOGIE | SERF_SHARED;
  289. X    if (OpenDevice(DeviceName, DeviceUnit, &Iosr, 0L)) {
  290. X    Iosr.IOSer.io_Device = NULL;
  291. X    xexit(21);
  292. X    }
  293. X
  294. X    InterceptDeviceVector(Iosr.IOSer.io_Device);
  295. X
  296. X    Iosw = Iosr;
  297. X
  298. X    Iosw.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE | SERF_SHARED;
  299. X    Iosw.io_ExtFlags = 0;
  300. X    Iosw.io_Baud = Bauds[0];
  301. X    Iosw.io_ReadLen = 8;
  302. X    Iosw.io_WriteLen = 8;
  303. X    Iosw.io_StopBits = 1;
  304. X
  305. X    SetParams(&Iosw);
  306. X
  307. X    /*
  308. X     *    Run Operation
  309. X     */
  310. X
  311. X    State = ST_WAITCD;
  312. X    Iot.tr_time.tv_secs = 1;
  313. X    Iot.tr_time.tv_micro= 0;
  314. X    IotIP = 1;
  315. X    SendIO(&Iot);
  316. X
  317. X    InitModem();
  318. X
  319. X    Signal(FindTask(NULL), IoSinkMask);
  320. X
  321. X    for (;;) {
  322. X    long mask;
  323. X    IOR  *ior;
  324. X    GMsg *msg;
  325. X    mask = Wait(SIGBREAKF_CTRL_C | IoSinkMask | ComPortMask);
  326. X
  327. X    ulog(2, "State = %d", State);
  328. X
  329. X    if (mask & SIGBREAKF_CTRL_C)
  330. X        break;
  331. X
  332. X    if (msg = (GMsg *)GetMsg(ComPort)) {
  333. X        do {
  334. X        switch(msg->Cmd) {
  335. X        case 'O':
  336. X            DoOptions(msg->Data1, msg->Data2);
  337. X            break;
  338. X        }
  339. X        ReplyMsg((MSG *)msg);
  340. X        if (ZeroOption)
  341. X            xexit(0);
  342. X        } while (msg = (GMsg *)GetMsg(ComPort));
  343. X        if (State == ST_WAITCD && !GotOffPort)
  344. X        Disconnect(0);
  345. X    }
  346. X
  347. X    while (ior = (IOR *)GetMsg(IoSink)) {
  348. X        if (ior == (IOR *)&Iot) {
  349. X        short diu;
  350. X
  351. X        IotIP = 0;
  352. X        Iot.tr_time.tv_secs = 1;
  353. X        Iot.tr_time.tv_micro= 0;
  354. X
  355. X        /*
  356. X         *  If OpenCnt > 1, disable all processing.
  357. X         *
  358. X         *  When returns to <= 1 reset serial port.
  359. X         */
  360. X
  361. X        diu = DeviceInUse();
  362. X        if (diu) {
  363. X            if (GotOffPort == 0) {
  364. X            ulog(-1, "Device in use");
  365. X            if (Locked)
  366. X                ulog(-1, "getting off port");
  367. X            SerialOff();
  368. X            GotOffPort = 1;
  369. X            State = ST_WAITCD;
  370. X            }
  371. X            SendIO(&Iot);
  372. X            IotIP = 1;
  373. X            continue;
  374. X        }
  375. X        if (GotOffPort) {
  376. X            if (Locked == 0) {
  377. X            LockSerialPort(DeviceName, DeviceUnit);
  378. X            Locked = 1;
  379. X            }
  380. X            GotOffPort = 0;
  381. X            ulog(-1, "Getty resetting");
  382. X            SendIO(&Iot);
  383. X            IotIP = 1;
  384. X            Disconnect(1);
  385. X            continue;
  386. X        }
  387. X        if (State == ST_WAITCD)
  388. X            SerialOff();
  389. X
  390. X        if (State != ST_WAITCD && IosrIP == 0) {
  391. X            if (Locked == 0)
  392. X            LockSerialPort(DeviceName, DeviceUnit);
  393. X            Locked = 1;
  394. X            ulog(-1, "Serial Port Locked");
  395. X
  396. X            Iosr.IOSer.io_Command = CMD_READ;
  397. X            Iosr.IOSer.io_Data = (APTR)RxBuf;
  398. X            Iosr.IOSer.io_Length = 1;
  399. X            SendIO(&Iosr);
  400. X            IosrIP = 1;
  401. X            ulog(1, "Carrier, Getty getting on port");
  402. X        }
  403. X
  404. X        Iosw.IOSer.io_Command = SDCMD_QUERY;
  405. X        DoIO(&Iosw);
  406. X        if (IgnoreCD)
  407. X            Iosw.io_Status &= ~CIAF_COMCD;
  408. X
  409. X        /*
  410. X         *  If state connected and we loose carrier, disconnect.
  411. X         *
  412. X         *  If state connected and timeout occurs disconnect.
  413. X         */
  414. X
  415. X        if (State != ST_WAITCD) {
  416. X            if ((Iosw.io_Status & CIAF_COMCD) != 0) {
  417. X            ulog(1, "Getty, Carrier lost");
  418. X            Disconnect(0);
  419. X            } else {
  420. X            if (--CountDown == 0) {
  421. X                ulog(1, "Getty, Timeout, Disconnecting");
  422. X                Disconnect(1);
  423. X                Iosw.io_Status |= CIAF_COMCD; /* for below */
  424. X            }
  425. X            }
  426. X        }
  427. X
  428. X        switch(State) {
  429. X        case ST_WAITCD:
  430. X            if ((Iosw.io_Status & CIAF_COMCD) == 0) {
  431. X            State = ST_CONNECT;
  432. X            CountDown = 60;     /*    allow 60 seconds */
  433. X            ulog(-1, "Carrier Detect");
  434. X            } else {
  435. X            Iot.tr_time.tv_secs = 2;
  436. X            }
  437. X            break;
  438. X        case ST_CONNECT:
  439. X            /*
  440. X             *    Wait for CONNECT message, then send Login:
  441. X             */
  442. X
  443. X            if (IgnoreConnect && HaveConnectMsg == 0) {
  444. X            if (Wire7)
  445. X                Set7Wire(&Iosw);
  446. X            HaveConnectMsg = 1;
  447. X            ulog(-1, "Connect");
  448. X            }
  449. X
  450. X            if (HaveConnectMsg) {
  451. X            FILE *fi;
  452. X
  453. X            Delay(50);
  454. X            ClearRecv();
  455. X            if (fi = fopen("Getty:Getty-Header", "r")) {
  456. X                while (fgets(ScrBuf, sizeof(ScrBuf), fi)) {
  457. X                SerPuts(ScrBuf);
  458. X                SerPuts("\r");
  459. X                }
  460. X                fclose(fi);
  461. X            }
  462. X            termCr = termLf = 1;
  463. X            SerPuts("Login: ");
  464. X            ulog(-1, "Getty, Connect, Login");
  465. X            State = ST_LOGIN;
  466. X            Index = 0;
  467. X            HaveLogin = 0;
  468. X            LoginBuf[0] = 0;
  469. X            }
  470. X            break;
  471. X        case ST_LOGIN:        /*    wait Login: response    */
  472. X            if (HaveLogin) {
  473. X            if (LoginBuf[0] == 0) {
  474. X                State = ST_CONNECT;
  475. X                break;
  476. X            }
  477. X            ClearRecv();
  478. X            PasswdBuf[0] = 0;
  479. X
  480. X            /*
  481. X             *  If no password required, else request
  482. X             *  password.
  483. X             */
  484. X
  485. X            if (CheckLoginAndPassword()) {
  486. X                HavePasswd = 1;
  487. X                Index = 0;
  488. X                State = ST_PASSWD;
  489. X            } else {
  490. X                SerPuts("Password: ");
  491. X                ulog(1, "Getty, Passwd");
  492. X                State = ST_PASSWD;
  493. X                HavePasswd = 0;
  494. X                Index = 0;
  495. X            }
  496. X            }
  497. X            break;
  498. X        case ST_PASSWD:     /*    wait Password: response */
  499. X            if (HavePasswd) {
  500. X            if (CheckLoginAndPassword()) {
  501. X                ulog(-1, "login %s", LoginBuf);
  502. X
  503. X                /*
  504. X                 *    Disable read requests but leave serial
  505. X                 *    port locked.
  506. X                 */
  507. X
  508. X                if (IosrIP) {
  509. X                AbortIO(&Iosr);
  510. X                WaitIO(&Iosr);
  511. X                IosrIP = 0;
  512. X                }
  513. X
  514. X                /*
  515. X                 *    If run successful, leave read req and
  516. X                 *    timer disabled.
  517. X                 */
  518. X
  519. X                RunPasswdEntry();
  520. X
  521. X                if (DropOnExit)
  522. X                Disconnect(1);
  523. X                else
  524. X                State = ST_CONNECT;
  525. X                ulog(-1, "disconnect");
  526. X            } else {
  527. X                SerPuts("Login Failed.\r\n\n");
  528. X                State = ST_CONNECT;
  529. X                ulog(-1, "LoginFailed user=%s pass=%s", LoginBuf, PasswdBuf);
  530. X            }
  531. X            HaveLogin = 0;
  532. X            HavePasswd= 0;
  533. X            LoginBuf[0] = 0;
  534. X            }
  535. X            break;
  536. X        }
  537. X
  538. X        /*
  539. X         *  Make no read requests while running 3rd party
  540. X         *  program, else resend read request.
  541. X         */
  542. X
  543. X        if (IotIP == 0) {
  544. X            IotIP = 1;
  545. X            SendIO(&Iot);
  546. X        }
  547. X        }
  548. X
  549. X        /*
  550. X         *    RECEIVED SERIAL READ DATA
  551. X         */
  552. X
  553. X        if (ior == (IOR *)&Iosr) {
  554. X        IosrIP = 0;
  555. X
  556. X        Iosw.IOSer.io_Command = SDCMD_QUERY;
  557. X        DoIO(&Iosw);
  558. X        if (IgnoreCD)
  559. X            Iosw.io_Status &= ~CIAF_COMCD;
  560. X
  561. X        /*
  562. X         *  BREAK used to switch baud rates between allowed
  563. X         *  values
  564. X         */
  565. X
  566. X        if (Iosw.io_Status & IO_STATF_READBREAK) {
  567. X            if (BaudAdjust == 0 && (State == ST_LOGIN || State == ST_PASSWD)) {
  568. X            if (++BIndex == arysize(Bauds))
  569. X                BIndex = 0;
  570. X            if (Bauds[BIndex] == 0)
  571. X                BIndex = 0;
  572. X            Iosw.io_Baud = Bauds[BIndex];
  573. X            SetParams(&Iosw);
  574. X            if (Wire7)
  575. X                Set7Wire(&Iosw);
  576. X            ulog(1, "<BREAK> to %d baud", Iosw.io_Baud);
  577. X            Delay(100);
  578. X            ClearRecv();
  579. X            Index = 0;
  580. X            State = ST_CONNECT;
  581. X            }
  582. X        } else
  583. X        if (Iosr.IOSer.io_Actual == 1) {
  584. X            char *ptr;
  585. X            UBYTE c = (UBYTE)RxBuf[0];
  586. X
  587. X            ulog(2, "Rx %02x %c", c, (c < 32) ? ' ' : c);
  588. X            c &= 0x7F;
  589. X
  590. X            switch(State) {
  591. X            case ST_WAITCD:    /*  looking for CONNECT msg */
  592. X            case ST_CONNECT:    /*  looking for CONNECT msg */
  593. X            ptr = ConnectBuf;
  594. X            break;
  595. X            case ST_LOGIN:    /*  looking for login name  */
  596. X            ptr = LoginBuf;
  597. X            break;
  598. X            case ST_PASSWD:    /*  looking for password    */
  599. X            ptr = PasswdBuf;
  600. X            break;
  601. X            }
  602. X            if (State == ST_LOGIN && HaveLogin)
  603. X            c = 0;
  604. X            if (State == ST_PASSWD && HavePasswd)
  605. X            c = 0;
  606. X
  607. X            switch(c) {
  608. X            case 0:
  609. X            break;
  610. X            case 8:
  611. X            if (State == ST_LOGIN && HaveLogin)
  612. X                break;
  613. X            if (Index) {
  614. X                if (State == ST_LOGIN)
  615. X                SerPuts("\010 \010");
  616. X                --Index;
  617. X            }
  618. X            break;
  619. X            case 10:
  620. X            if (termLf == 0)
  621. X                break;
  622. X            termCr = 0;
  623. X            case 13:
  624. X            if (c == 13) {
  625. X                if (termCr == 0)
  626. X                break;
  627. X                else
  628. X                termLf = 0;
  629. X            }
  630. X            ptr[Index] = 0;
  631. X            Index = 0;
  632. X            switch(State) {
  633. X            case ST_WAITCD:
  634. X            case ST_CONNECT:
  635. X                if (strncmp(ptr, "CONNECT", 7)) {
  636. X                ulog(1, "Looking for CONNECT, got '%s'", ptr);
  637. X                break;
  638. X                }
  639. X                Delay(50);
  640. X                HaveConnectMsg = 1;
  641. X                if (BaudAdjust) {
  642. X                ulog(-1, "Connect Auto-Baud %d", Iosw.io_Baud);
  643. X                } else {
  644. X                char *str = ptr + 7;
  645. X                while (*str && (*str == 9 || *str == ' '))
  646. X                    ++str;
  647. X                if (*str >= '0' && *str <= '9')
  648. X                    Iosw.io_Baud = atoi(str);
  649. X                else
  650. X                    Iosw.io_Baud = Bauds[0];
  651. X                SetParams(&Iosw);
  652. X                ulog(-1, "Connect at %d baud", Iosw.io_Baud);
  653. X                }
  654. X                if (Wire7)
  655. X                Set7Wire(&Iosw);
  656. X                break;
  657. X            case ST_LOGIN:
  658. X                HaveLogin = 1;
  659. X                SerPuts("\r\n");
  660. X                ulog(1, "Login: %s", ptr);
  661. X                break;
  662. X            case ST_PASSWD:
  663. X                HavePasswd = 1;
  664. X                SerPuts("\r\n");
  665. X                ulog(1, "Password: %s", ptr);
  666. X                break;
  667. X            }
  668. X            break;
  669. X            default:
  670. X            if (Index == 31)
  671. X                break;
  672. X            if (State == ST_LOGIN) {
  673. X                char cc[2];
  674. X                cc[0] = c;
  675. X                cc[1] = 0;
  676. X                SerPuts(cc);
  677. X            }
  678. X            ptr[Index++] = c;
  679. X            break;
  680. X            }
  681. X        }
  682. X        if (IosrIP == 0) {
  683. X            Iosr.IOSer.io_Command = CMD_READ;
  684. X            Iosr.IOSer.io_Data = (APTR)RxBuf;
  685. X            Iosr.IOSer.io_Length = 1;
  686. X            SendIO(&Iosr);
  687. X            IosrIP = 1;
  688. X        }
  689. X        }
  690. X    }
  691. X    }
  692. X    xexit(0);
  693. X}
  694. X
  695. Xvoid
  696. XSerialOff()
  697. X{
  698. X    if (IosrIP) {
  699. X    AbortIO(&Iosr);
  700. X    WaitIO(&Iosr);
  701. X    IosrIP = 0;
  702. X    }
  703. X    if (Locked) {
  704. X    UnLockSerialPort(DeviceName, DeviceUnit);
  705. X    Locked = 0;
  706. X    ulog(1, "Serial Port UnLocked");
  707. X    }
  708. X}
  709. X
  710. Xvoid
  711. Xxexit(code)
  712. X{
  713. X    if (ComPortMask) {
  714. X    GMsg *msg;
  715. X    Forbid();
  716. X    while (msg = (GMsg *)GetMsg(ComPort))
  717. X        ReplyMsg((MSG *)msg);
  718. X    DeletePort(ComPort);
  719. X    Permit();
  720. X    }
  721. X    if (IotIP) {
  722. X    AbortIO(&Iot);
  723. X    WaitIO(&Iot);
  724. X    }
  725. X    if (Iot.tr_node.io_Device)
  726. X    CloseDevice(&Iot);
  727. X
  728. X    if (IosrIP) {
  729. X    AbortIO(&Iosr);
  730. X    WaitIO(&Iosr);
  731. X    }
  732. X    if (Iosr.IOSer.io_Device) {
  733. X    RestoreDeviceVector(Iosr.IOSer.io_Device);
  734. X    CloseDevice(&Iosr);
  735. X    }
  736. X
  737. X    if (IoSink)
  738. X    DeletePort(IoSink);
  739. X
  740. X    if (NullFH)
  741. X    Close(NullFH);
  742. X
  743. X    if (Locked)
  744. X    UnLockSerialPort(DeviceName, DeviceUnit);
  745. X
  746. X    exit(code);
  747. X}
  748. X
  749. Xvoid
  750. XSerPuts(str)
  751. Xchar *str;
  752. X{
  753. X    Iosw.IOSer.io_Command = CMD_WRITE;
  754. X    Iosw.IOSer.io_Data = (APTR)str;
  755. X    Iosw.IOSer.io_Length = strlen(str);
  756. X    DoIO(&Iosw);
  757. X}
  758. X
  759. Xstatic short RxDisableIP;
  760. X
  761. Xvoid
  762. XRxDisable()
  763. X{
  764. X    RxDisableIP = IosrIP;
  765. X    if (IosrIP) {
  766. X    AbortIO(&Iosr);
  767. X    WaitIO(&Iosr);
  768. X    IosrIP = 0;
  769. X    }
  770. X}
  771. X
  772. Xvoid
  773. XRxEnable()
  774. X{
  775. X    if (RxDisableIP && IosrIP == 0) {
  776. X    Iosr.IOSer.io_Command = CMD_READ;
  777. X    Iosr.IOSer.io_Data = (APTR)RxBuf;
  778. X    Iosr.IOSer.io_Length = 1;
  779. X    SendIO(&Iosr);
  780. X    IosrIP = 1;
  781. X    }
  782. X}
  783. X
  784. Xvoid
  785. XClearRecv()
  786. X{
  787. X    RxDisable();
  788. X    ulog(1, "Clear beg");
  789. X    for (;;) {
  790. X    Iosr.IOSer.io_Command = SDCMD_QUERY;
  791. X    DoIO(&Iosr);
  792. X    if ((Iosr.IOSer.io_Length = Iosr.IOSer.io_Actual) <= 0)
  793. X        break;
  794. X    if (Iosr.IOSer.io_Length > sizeof(RxBuf))
  795. X        Iosr.IOSer.io_Length = sizeof(RxBuf);
  796. X    Iosr.IOSer.io_Data = (APTR)RxBuf;
  797. X    Iosr.IOSer.io_Command = CMD_READ;
  798. X    DoIO(&Iosr);
  799. X    }
  800. X    ulog(1, "Clear end");
  801. X    RxEnable();
  802. X}
  803. X
  804. Xvoid
  805. XSetParams(ior)
  806. XIOSER *ior;
  807. X{
  808. X    int error;
  809. X
  810. X    if (IosrIP)
  811. X    AbortIO(&Iosr);
  812. X    ior->IOSer.io_Command = SDCMD_SETPARAMS;
  813. X    error = DoIO(ior);
  814. X    if (error)
  815. X    printf("SetParams, error %d\n", error);
  816. X}
  817. X
  818. Xvoid
  819. XSet7Wire(ior)
  820. XIOSER *ior;
  821. X{
  822. X    short error;
  823. X
  824. X    if (IosrIP)
  825. X    AbortIO(&Iosr);
  826. X    ior->IOSer.io_Command = SDCMD_SETPARAMS;
  827. X    ior->io_SerFlags |= SERF_7WIRE;
  828. X    error = DoIO(ior);
  829. X    ior->io_SerFlags &= ~SERF_7WIRE;
  830. X    if (error)
  831. X    printf("SetParams, error %d\n", error);
  832. X}
  833. X
  834. Xvoid
  835. XDisconnect(dropdtr)
  836. X{
  837. X    short retry = (IgnoreDTR) ? 2 : 10;
  838. X
  839. X    ulog(1, "Disconnect drop=%d", dropdtr);
  840. X    HaveConnectMsg = 0;
  841. X    HaveLogin    = 0;
  842. X    HavePasswd    = 0;
  843. X    LoginBuf[0] = 0;
  844. X    PasswdBuf[0] = 0;
  845. X    Index = 0;
  846. X    State = ST_WAITCD;
  847. X
  848. X    while (dropdtr && DeviceInUse() == 0) {
  849. X    short i;
  850. X
  851. X    RxDisable();
  852. X
  853. X    if (IgnoreDTR) {
  854. X        if (ModemType != 'd') {
  855. X        Delay(70);
  856. X        SerPuts("+++");
  857. X        Delay(70);
  858. X        SerPuts("\010\010\r");
  859. X        Delay(10);
  860. X        SerPuts("ATH0\r");
  861. X        Delay(120);
  862. X        }
  863. X    } else {
  864. X        CloseDevice(&Iosr);
  865. X        Iosr.IOSer.io_Device = NULL;    /*    so xexit doesn't reclose */
  866. X        for (i = 0; i < 5; ++i) {       /*  5 seconds   */
  867. X        Delay(50);
  868. X        if (SetSignal(SIGBREAKF_CTRL_C, 0) & SIGBREAKF_CTRL_C)
  869. X            xexit(23);
  870. X        }
  871. X
  872. X       /*
  873. X        *  Use Iosr to re-open serial device so we don't loose
  874. X        *  our config.
  875. X        */
  876. X
  877. X        if (OpenDevice(DeviceName, DeviceUnit, &Iosr, 0)) {
  878. X        Iosr.IOSer.io_Device = NULL;
  879. X        xexit(22);
  880. X        }
  881. X        Iosw.IOSer.io_Device = Iosr.IOSer.io_Device;
  882. X        Iosw.IOSer.io_Unit = Iosr.IOSer.io_Unit;
  883. X        SetParams(&Iosw);
  884. X    }
  885. X
  886. X    /*
  887. X     *  Loop until carrier lost
  888. X     */
  889. X
  890. X    Iosw.IOSer.io_Command = SDCMD_QUERY;
  891. X    DoIO(&Iosw);
  892. X    if (IgnoreCD)
  893. X        Iosw.io_Status &= ~CIAF_COMCD;
  894. X
  895. X    RxEnable();
  896. X
  897. X    if ((Iosw.io_Status & CIAF_COMCD) != 0)
  898. X        break;
  899. X    if (--retry == 0) {
  900. X        if (IgnoreDTR == 0)
  901. X        puts("Getty: unable to disconnect!");
  902. X        break;
  903. X    }
  904. X    }
  905. X    if (DeviceInUse() == 0)
  906. X    InitModem();
  907. X}
  908. X
  909. Xvoid
  910. XInitModem()
  911. X{
  912. X    char buf[64];
  913. X    short i;
  914. X
  915. X    RxDisable();
  916. X    ulog(1, "Init Modem");
  917. X    Iosw.io_Baud = Bauds[0];    /*  reset baud rate */
  918. X    BIndex = 0;
  919. X    SetParams(&Iosw);
  920. X    RxEnable();
  921. X
  922. X    switch(ModemType) {
  923. X    case 'm':               /*  Multi Modem     */
  924. X    SerPuts("\010\010\r");
  925. X    Delay(10);
  926. X    SerPuts("AT\r");
  927. X    Delay(50);
  928. X    sprintf(buf, "ATM%dS0=%dX4$BA%d&E%d\r",
  929. X        SpeakerLevel,
  930. X        AnswerRing,
  931. X        !BaudAdjust,
  932. X        (Wire7) ? 4 : 3
  933. X    );
  934. X    SerPuts(buf);
  935. X    break;
  936. X    case 'h':
  937. X    SerPuts("\010\010\r");
  938. X    Delay(10);
  939. X    SerPuts("ATZ\r");
  940. X    Delay(120);
  941. X    strcpy(buf, "AT");
  942. X    if (SpeakerOpt)
  943. X        sprintf(buf + strlen(buf), "M%d", SpeakerLevel);
  944. X    sprintf(buf + strlen(buf), "S0=%d", AnswerRing);
  945. X    strcat(buf, "\r");
  946. X    SerPuts(buf);
  947. X    break;
  948. X    case 'd':
  949. X    SerPuts("\010\010\r");
  950. X    break;
  951. X    }
  952. X    for (i = 0; i < arysize(AtFields) && AtFields[i]; ++i) {
  953. X    Delay(50);
  954. X    SerPuts(AtFields[i]);
  955. X    SerPuts("\r");
  956. X    }
  957. X    Delay(20);
  958. X    ClearRecv();
  959. X    Index = 0;
  960. X}
  961. X
  962. Xvoid
  963. XDoOptions(ac, av)
  964. Xchar *av[];
  965. X{
  966. X    short i;
  967. X    short bi = 0;
  968. X    short fi = 0;
  969. X    long v;
  970. X
  971. X    for (i = 1; i < ac; ++i) {
  972. X    char *ptr = av[i];
  973. X    if (*ptr != '-') {
  974. X        if (fi != arysize(AtFields))
  975. X        AtFields[fi++] = ptr;
  976. X        else
  977. X        puts("AT field overflow");
  978. X        continue;
  979. X    }
  980. X    if (*++ptr)             /*  skip -      */
  981. X        ++ptr;        /*  and option    */
  982. X    v = atoi(ptr);
  983. X    switch(ptr[-1]) {
  984. X    case '0':
  985. X        ZeroOption = 1;
  986. X        break;
  987. X    case '7':
  988. X        Wire7 = 1;
  989. X        break;
  990. X    case 'S':
  991. X        DeviceName = ptr;
  992. X        break;
  993. X    case 'U':
  994. X        DeviceUnit = v;
  995. X        break;
  996. X    case 'M':
  997. X        ModemType = *ptr;
  998. X        break;
  999. X    case 'A':
  1000. X        BaudAdjust = 1;
  1001. X        break;
  1002. X    case 'B':
  1003. X        if (bi != arysize(Bauds))
  1004. X        Bauds[bi++] = v;
  1005. X        else
  1006. X        puts("-B field overflow");
  1007. X        break;
  1008. X    case 'm':
  1009. X        SpeakerOpt = 1;
  1010. X        SpeakerLevel = v;
  1011. X        break;
  1012. X    case 'r':
  1013. X        AnswerRing = v;
  1014. X        break;
  1015. X    case 'h':
  1016. X        IgnoreCD = !v;
  1017. X        break;
  1018. X    case 'c':
  1019. X        IgnoreConnect = !v;
  1020. X        break;
  1021. X    case 'd':
  1022. X        IgnoreDTR = !v;
  1023. X        break;
  1024. X    case 'x':
  1025. X        LogLevel = v;
  1026. X        LogToStdout = (v >= 0);
  1027. X        break;
  1028. X    default:
  1029. X        printf("Warning, Bad option: -%s\n", ptr);
  1030. X        break;
  1031. X    }
  1032. X    }
  1033. X    if (fi && fi != arysize(AtFields))
  1034. X    AtFields[fi] = NULL;
  1035. X    if (bi && bi != arysize(Bauds))
  1036. X    Bauds[bi] = 0;
  1037. X}
  1038. X
  1039. XDeviceInUse()
  1040. X{
  1041. X    return(Iosr.IOSer.io_Device->dd_Library.lib_OpenCnt > 1);
  1042. X}
  1043. X
  1044. X/*
  1045. X *  Device Vector Intercept, used to force SERF_SHARED on device open.
  1046. X */
  1047. X
  1048. Xextern void AsmIntercept();
  1049. Xextern void AsmRoute();
  1050. XFPTR OldVector;
  1051. X
  1052. Xvoid
  1053. XInterceptDeviceVector(dev)
  1054. Xstruct Device *dev;
  1055. X{
  1056. X    OldVector = SetFunction((struct Library *)dev, LIB_OPEN, AsmIntercept);
  1057. X    AsmRoute(OldVector);
  1058. X}
  1059. X
  1060. Xvoid
  1061. XRestoreDeviceVector(dev)
  1062. Xstruct Device *dev;
  1063. X{
  1064. X    SetFunction((struct Library *)dev, LIB_OPEN, OldVector);
  1065. X}
  1066. X
  1067. X
  1068. END_OF_FILE
  1069. if test 20766 -ne `wc -c <'uucp2/src/getty/getty.c'`; then
  1070.     echo shar: \"'uucp2/src/getty/getty.c'\" unpacked with wrong size!
  1071. fi
  1072. # end of 'uucp2/src/getty/getty.c'
  1073. fi
  1074. if test -f 'uucp2/src/uucico/gio.c' -a "${1}" != "-c" ; then 
  1075.   echo shar: Will not clobber existing file \"'uucp2/src/uucico/gio.c'\"
  1076. else
  1077. echo shar: Extracting \"'uucp2/src/uucico/gio.c'\" \(18871 characters\)
  1078. sed "s/^X//" >'uucp2/src/uucico/gio.c' <<'END_OF_FILE'
  1079. X
  1080. X/*
  1081. X *  GIO.C    WINDOWED G PROTOCOL
  1082. X *
  1083. X *  written from scratch, except the checksum routine which was
  1084. X *  rewritten but based on the old one.
  1085. X *
  1086. X *  WINDOW SIZE:    When changing the window size be sure there
  1087. X *            are enough buffers available for pending txs.
  1088. X *
  1089. X *  GIO.C (c)Copyright 1989, Matthew Dillon, All Rights Reserved
  1090. X *  extended to window size of 7 by Jack J. Rouse
  1091. X */
  1092. X
  1093. X#include "includes.h"
  1094. X
  1095. Xtypedef unsigned char    ubyte;
  1096. Xtypedef unsigned short    uword;
  1097. X
  1098. Xtypedef struct {
  1099. X    ubyte   Dle;    /*  Literal ASCII DLE                */
  1100. X    ubyte   K;        /*  data size 2^(K+4) except K=0 means no data  */
  1101. X    ubyte   CL,CH;    /*  MAGIC - chksum(data) ^ C        */
  1102. X    ubyte   C;
  1103. X    ubyte   X;        /*  K ^ C0 ^ C1 ^ C            */
  1104. X} Frame;
  1105. X
  1106. Xtypedef struct {
  1107. X    ubyte   CType;    /*  bits 7-6 of C    */
  1108. X    ubyte   CCmd;    /*  bits 5-3 of C    */
  1109. X    ubyte   CSeq;    /*  bits 2-0 of C    */
  1110. X    ubyte   PLen;    /*  pre-data (2 bytes) for SHORTDATA type */
  1111. X    ubyte   *Data;    /*  implies CType=LONGDATA or SHORTDATA */
  1112. X    uword   DLen;    /*  length of data    */
  1113. X} Packet;
  1114. X
  1115. XPrototype int gwrdata(FILE *);
  1116. XPrototype int gwrmsg(char *);
  1117. XPrototype int grddata(FILE *);
  1118. XPrototype int grdmsg(char *, int);
  1119. XPrototype int gturnon(int);
  1120. XPrototype int gturnoff(void);
  1121. XPrototype void ResetGIO(void);
  1122. X
  1123. XLocal      char *GetTxBuf(void);
  1124. XLocal      int SendDataPacket(unsigned char *, int);
  1125. XLocal      int RecvDataPacket(char **);
  1126. XLocal      int GetData(int, Packet *);
  1127. XLocal      int RecvdAck(char);
  1128. XLocal      int WriteCtlPacket(int);
  1129. XLocal      int WritePacket(Packet *, int);
  1130. XLocal      int ReadPacket(Packet *, int);
  1131. XLocal      int CheckSum(unsigned char *, int);
  1132. XLocal      void FrameToPacket(Frame *, Packet *, unsigned char *);
  1133. XLocal      int LenToK(unsigned short);
  1134. X
  1135. Xextern int debug;
  1136. Xextern int WindowOne;
  1137. X
  1138. X#define SUCCESS 0
  1139. X#define FAIL    1
  1140. X
  1141. X#define MAGIC        0125252
  1142. X#define DLE        0x10
  1143. X#define WINDOWSIZE  7
  1144. X#define SEGSIZEK    2        /*  64 bytes ??     */
  1145. X
  1146. X#define SUB1(var)   (((var)-1)&7)
  1147. X
  1148. X
  1149. X#define CT_CONTROL    (0 << 6)
  1150. X#define CT_ALTCHN    (1 << 6)
  1151. X#define CT_LONGDATA    (2 << 6)
  1152. X#define CT_SHORTDATA    (3 << 6)
  1153. X#define CT_MASK     (3 << 6)
  1154. X
  1155. X#define CC_CLOSE    (1 << 3)
  1156. X#define CC_RJ        (2 << 3)
  1157. X#define CC_SRJ        (3 << 3)
  1158. X#define CC_RR        (4 << 3)
  1159. X#define CC_INITC    (5 << 3)
  1160. X#define CC_INITB    (6 << 3)
  1161. X#define CC_INITA    (7 << 3)
  1162. X#define CC_MASK     (7 << 3)
  1163. X
  1164. X#define SEQ_MASK    7
  1165. X
  1166. X#define WAIT_ACK    1
  1167. X#define WAIT_DATA    2
  1168. X#define WAIT_CONTROL    3
  1169. X
  1170. X#define MaxPktSize    4096
  1171. X
  1172. Xchar    RxBuf[MaxPktSize+4];
  1173. Xchar    *TxBuf[8];
  1174. X
  1175. X                /*  TRANSMIT STAGE        */
  1176. Xchar    TxSeq = 0;        /*  Last send packet        */
  1177. Xchar    TxPend= 0;        /*  hasn't been acked yet   */
  1178. Xuword    TxWinSize;        /*  1 or 2 (max 7)          */
  1179. Xuword    TxSegSize;        /*  maximum segment size    */
  1180. Xchar    TxSegK;         /*  K for TxSegSize        */
  1181. XPacket    TxPacket[8];        /*  contents of last packet */
  1182. X
  1183. X                /*  RECEIVE STAGE        */
  1184. Xchar    RxSeq = 0;        /*  Last valid recv pkt     */
  1185. Xchar    RxRdy = 0;        /*  Has come in..        */
  1186. Xchar    RxRetry = 8;
  1187. Xchar    RxNotAcked = 0;     /*  We have yet to ack it   */
  1188. XPacket    RxPacket;        /*  The packet that has come in */
  1189. X
  1190. Xvoid
  1191. XResetGIO()
  1192. X{
  1193. X    TxSeq = 0;
  1194. X    TxPend= 0;
  1195. X    TxWinSize = 0;
  1196. X    TxSegSize = 0;
  1197. X    TxSegK = 0;
  1198. X    RxSeq = 0;
  1199. X    RxRdy = 0;
  1200. X    RxRetry = 8;
  1201. X    RxNotAcked = 0;
  1202. X}
  1203. X
  1204. X/*
  1205. X *  Get Transmit Buffer.  Note that some space to the left is available
  1206. X */
  1207. X
  1208. XLocal
  1209. Xchar *
  1210. XGetTxBuf()
  1211. X{
  1212. X    static int index = 0;
  1213. X
  1214. X    if (++index > TxWinSize)
  1215. X    index = 0;
  1216. X    if (TxBuf[index] == NULL
  1217. X    &&    (TxBuf[index] = (char *)malloc(MaxPktSize+4)) == NULL)
  1218. X    {
  1219. X    printf("Out of memory in GetTxBuf.");
  1220. X    /* could handle this case better, but it should be rare */
  1221. X    xexit(1);
  1222. X    }
  1223. X    return(TxBuf[index] + 2);
  1224. X}
  1225. X
  1226. Xint
  1227. Xgwrdata(fi)
  1228. XFILE *fi;
  1229. X{
  1230. X    int bytes;
  1231. X
  1232. X    if (debug > 7)
  1233. X    printf("GWRDATA: ");
  1234. X
  1235. X    for (;;) {
  1236. X    char *buf = GetTxBuf();
  1237. X    if ((bytes = fread(buf, 1, TxSegSize, fi)) <= 0)
  1238. X        break;
  1239. X    if (SendDataPacket(buf, bytes) != SUCCESS) {
  1240. X        if (debug > 7)
  1241. X        printf("GWR Failed\n");
  1242. X        return(FAIL);
  1243. X    }
  1244. X    if (debug > 7)
  1245. X        printf("\nGWROK ");
  1246. X    }
  1247. X    {
  1248. X    char *buf = GetTxBuf();
  1249. X    if (SendDataPacket(buf, 0) != SUCCESS) {
  1250. X        if (debug > 7)
  1251. X        printf("GWR Failed (last)\n");
  1252. X        return(FAIL);
  1253. X    }
  1254. X    }
  1255. X    if (debug > 7)
  1256. X    printf("\nGWFile Last Ack\n");
  1257. X    while (TxPend) {
  1258. X    if (GetData(WAIT_ACK, NULL) == FAIL)
  1259. X        return(FAIL);
  1260. X    }
  1261. X    if (debug > 7)
  1262. X    printf("success\n");
  1263. X    return (SUCCESS);
  1264. X}
  1265. X
  1266. X/*
  1267. X *  Write message to the other guy.
  1268. X *
  1269. X *  NOTE: LONGDATA packets used exclusively and \0 fill to end.
  1270. X */
  1271. X
  1272. Xint
  1273. Xgwrmsg(str)
  1274. Xchar *str;
  1275. X{
  1276. X    int len = strlen(str) + 1;      /*  type + str + \0  */
  1277. X
  1278. X    if (debug > 7)
  1279. X    printf("GWRMSG: %s\n", str);
  1280. X
  1281. X    while (len > TxSegSize) {
  1282. X    char *buf = GetTxBuf();
  1283. X    movmem(str, buf, TxSegSize);
  1284. X    if (debug > 7)
  1285. X        printf("GWR-SEND %d\n", TxSegSize);
  1286. X    if (SendDataPacket(buf, TxSegSize) != SUCCESS)
  1287. X        return(FAIL);
  1288. X    len -= TxSegSize;
  1289. X    str += TxSegSize;
  1290. X    }
  1291. X
  1292. X    /*
  1293. X     *    Find optimal packet size (remember, we must force LONGDATA
  1294. X     *
  1295. X     *    Apparently packet sizes less than the agreed upon size are
  1296. X     *    not allowed ???
  1297. X     */
  1298. X
  1299. X    {
  1300. X    short siz = TxSegSize;
  1301. X    char *buf = GetTxBuf();
  1302. X#ifdef NOTDEF
  1303. X    short k = TxSegK;
  1304. X
  1305. X    while (k > 1 && (siz >> 1) >= len) {
  1306. X        --k;
  1307. X        siz >>= 1;
  1308. X    }
  1309. X#endif
  1310. X    if (debug > 7)
  1311. X        printf("GWR-FNL %d %d\n", len, siz);
  1312. X
  1313. X    movmem(str, buf, len);
  1314. X    setmem(buf + len, siz - len, 0);
  1315. X    if (SendDataPacket(buf, siz) != SUCCESS) {
  1316. X        if (debug > 7)
  1317. X        printf("GWR-FAIL\n");
  1318. X        return(FAIL);
  1319. X    }
  1320. X    }
  1321. X    if (debug > 7)
  1322. X    printf("GWR Last Ack\n");
  1323. X    while (TxPend) {
  1324. X    if (GetData(WAIT_ACK, NULL) == FAIL)
  1325. X        return(FAIL);
  1326. X    }
  1327. X    if (debug > 7)
  1328. X    printf("success\n");
  1329. X    return (SUCCESS);
  1330. X}
  1331. X
  1332. Xint
  1333. Xgrddata(fi)
  1334. XFILE *fi;
  1335. X{
  1336. X    int bytes;
  1337. X    char *buf;
  1338. X
  1339. X    if (debug > 7)
  1340. X    printf("GRDDATA\n");
  1341. X    while ((bytes = RecvDataPacket(&buf)) > 0) {
  1342. X    if (debug > 7)
  1343. X        printf("GRDDATA blk %d\n", bytes);
  1344. X    fwrite(buf, 1, bytes, fi);
  1345. X    }
  1346. X    if (debug > 7)
  1347. X    printf("GRDDATA end %d\n", bytes);
  1348. X    if (bytes < 0)
  1349. X    return(FAIL);
  1350. X    else
  1351. X    return(SUCCESS);
  1352. X}
  1353. X
  1354. Xint
  1355. Xgrdmsg(buf, maxlen)
  1356. Xchar *buf;
  1357. X{
  1358. X    short i;
  1359. X    short n;
  1360. X    short slen;
  1361. X    char *ptr;
  1362. X
  1363. X    i = 0;
  1364. X    if (debug > 7)
  1365. X    printf("GRDMSG\n");
  1366. X    while ((n = RecvDataPacket(&ptr)) > 0) {
  1367. X    ptr[n] = 0;
  1368. X    slen = strlen(ptr);
  1369. X    if (slen > maxlen - 1) {
  1370. X        printf("GRDMSG: Buffer overflow!\n");
  1371. X        return (FAIL);
  1372. X    }
  1373. X    movmem(ptr, buf + i, slen);
  1374. X    buf[i + slen] = 0;
  1375. X    if (slen != n)
  1376. X        break;
  1377. X    i += slen;
  1378. X    maxlen -= slen;
  1379. X    }
  1380. X    if (debug > 7)
  1381. X    printf("GRDMSGEND %d (%d) %s\n", n, i, buf);
  1382. X    if (n < 0) {
  1383. X    buf[0] = 0;
  1384. X    return(FAIL);
  1385. X    }
  1386. X    return(SUCCESS);
  1387. X}
  1388. X
  1389. XLocal
  1390. Xint
  1391. XSendDataPacket(buf, bytes)
  1392. Xubyte *buf;
  1393. Xint bytes;
  1394. X{
  1395. X    Packet  P;
  1396. X
  1397. X    /*
  1398. X     *    If window exhausted we must wait for at least one ack.
  1399. X     */
  1400. X
  1401. X    while (TxPend == TxWinSize) {
  1402. X    if (GetData(WAIT_ACK, NULL) == FAIL)
  1403. X        return(FAIL);
  1404. X    }
  1405. X
  1406. X    TxSeq = (TxSeq + 1) & 7;        /*  next Tx packet  */
  1407. X
  1408. X    /*
  1409. X     *    Figure out best fit packet size.  Apparently packets smaller
  1410. X     *    then the agreed upon size are not allowed ???
  1411. X     */
  1412. X
  1413. X#ifdef NOTDEF
  1414. X    {
  1415. X    short k = TxSegK;
  1416. X    P.DLen = TxSegSize;
  1417. X    while (k > 1 && P.DLen && (P.DLen >> 1) >= bytes) {
  1418. X        --k;
  1419. X        P.DLen >>= 1;
  1420. X    }
  1421. X    }
  1422. X#else
  1423. X    P.DLen = TxSegSize;
  1424. X#endif
  1425. X
  1426. X    if (bytes < P.DLen) {
  1427. X    uword extra = P.DLen - bytes;
  1428. X    setmem(buf + bytes, extra, 0);
  1429. X    if (extra <= 127) {
  1430. X        P.PLen = 1;
  1431. X        buf[-1] = extra;
  1432. X    } else {
  1433. X        P.PLen = 2;
  1434. X        buf[-2] = 0x80 | extra;
  1435. X        buf[-1] = (extra >> 7);
  1436. X    }
  1437. X    P.CType = CT_SHORTDATA;
  1438. X    } else {
  1439. X    P.PLen = 0;
  1440. X    P.CType = CT_LONGDATA;
  1441. X    }
  1442. X    P.CCmd = TxSeq << 3;    /*  transmit sequence number */
  1443. X    P.CSeq = RxSeq;        /*  last valid received pkt  */
  1444. X    P.Data = buf;
  1445. X
  1446. X    if (debug > 7)
  1447. X    printf("WRITE DATA PACKET txseq=%d rxack=%d\n", TxSeq, P.CSeq);
  1448. X
  1449. X    RxNotAcked = 0;        /*  We've acked the rx packet */
  1450. X
  1451. X    TxPacket[TxSeq] = P;
  1452. X    ++TxPend;
  1453. X
  1454. X    WritePacket(&TxPacket[TxSeq], 1);
  1455. X
  1456. X    return(SUCCESS);
  1457. X}
  1458. X
  1459. XLocal
  1460. Xint
  1461. XRecvDataPacket(pbuf)
  1462. Xchar **pbuf;
  1463. X{
  1464. X    if (RxRdy == 0) {
  1465. X    if (GetData(WAIT_DATA, NULL) != SUCCESS)
  1466. X        return(-1);
  1467. X    }
  1468. X    *pbuf = RxPacket.Data;
  1469. X    RxRdy = 0;
  1470. X    return((int)RxPacket.DLen);
  1471. X}
  1472. X
  1473. Xint
  1474. Xgturnon(master)
  1475. Xint master;
  1476. X{
  1477. X    Packet P;
  1478. X    short retry = 5;
  1479. X    short windowsize = WINDOWSIZE;    /*  our prefered window size */
  1480. X    short segsize = SEGSIZEK;        /*  our prefered segment size */
  1481. X
  1482. X    if (WindowOne)
  1483. X    windowsize = 1;
  1484. X
  1485. X    if (master) {
  1486. X    while (retry > 0) {
  1487. X        WriteCtlPacket(CC_INITA | windowsize);
  1488. X        if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITA) {
  1489. X        if (P.CSeq && P.CSeq < windowsize)
  1490. X            windowsize = P.CSeq;
  1491. X        break;
  1492. X        }
  1493. X        --retry;
  1494. X    }
  1495. X    while (retry > 0) {
  1496. X        WriteCtlPacket(CC_INITB | (segsize - 1));
  1497. X        if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITB) {
  1498. X        if (P.CSeq < segsize - 1)
  1499. X            segsize = P.CSeq + 1;
  1500. X        break;
  1501. X        }
  1502. X        --retry;
  1503. X    }
  1504. X    while (retry > 0) {
  1505. X        WriteCtlPacket(CC_INITC | windowsize);
  1506. X        if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITC) {
  1507. X        if (P.CSeq && P.CSeq < windowsize)
  1508. X            windowsize = P.CSeq;
  1509. X        break;
  1510. X        }
  1511. X        --retry;
  1512. X    }
  1513. X    } else {
  1514. X    while (retry > 0) {
  1515. X        if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITA) {
  1516. X        WriteCtlPacket(CC_INITA | windowsize);
  1517. X        if (P.CSeq && windowsize > P.CSeq)
  1518. X            windowsize = P.CSeq;
  1519. X        break;
  1520. X        }
  1521. X        --retry;
  1522. X    }
  1523. X    while (retry > 0) {
  1524. X        if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITB) {
  1525. X        WriteCtlPacket(CC_INITB | (segsize - 1));
  1526. X        if (P.CSeq < segsize - 1)
  1527. X            segsize = P.CSeq + 1;
  1528. X        break;
  1529. X        }
  1530. X        --retry;
  1531. X    }
  1532. X    while (retry > 0) {
  1533. X        if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_INITC) {
  1534. X        WriteCtlPacket(CC_INITC | windowsize);
  1535. X        if (P.CSeq && windowsize > P.CSeq)
  1536. X            windowsize = P.CSeq;
  1537. X        break;
  1538. X        }
  1539. X        --retry;
  1540. X    }
  1541. X    }
  1542. X    TxSegK = segsize;
  1543. X    TxSegSize = 1 << (TxSegK + 4);
  1544. X    TxWinSize = windowsize;
  1545. X    if (debug > 0)
  1546. X    printf("Window Size is %d\n", TxWinSize);
  1547. X    if (retry == 0)
  1548. X    return(FAIL);
  1549. X    return(SUCCESS);
  1550. X}
  1551. X
  1552. Xint
  1553. Xgturnoff()
  1554. X{
  1555. X    Packet P;
  1556. X
  1557. X    WriteCtlPacket(CC_CLOSE);
  1558. X    if (GetData(WAIT_CONTROL, &P) == SUCCESS && P.CCmd == CC_CLOSE) {
  1559. X    WriteCtlPacket(CC_RR | RxSeq);
  1560. X    return (SUCCESS);
  1561. X    }
  1562. X    return (FAIL);
  1563. X}
  1564. X
  1565. X/*
  1566. X *  GetData()
  1567. X *
  1568. X *  This is the core of the packet protocol.  As soon as we get a satisfactory
  1569. X *  terminating condition we return.  However, on unsatisfactory conditions
  1570. X *  such as having to send a reject, we attempt to drain any pending data
  1571. X *  (i.e. multiple returned rejects) so we do not do multiple resends.
  1572. X *
  1573. X *  The resend flag only applies on a failure return.
  1574. X */
  1575. X
  1576. XLocal
  1577. Xint
  1578. XGetData(waitfor, p)
  1579. Xint waitfor;
  1580. XPacket *p;
  1581. X{
  1582. X    Packet P;
  1583. X    short timeout;
  1584. X    short drainmode = 0;
  1585. X
  1586. X    /*
  1587. X     *    If we haven't acked the last packet we received we must do
  1588. X     *    so now before we can expect to receive another one!
  1589. X     */
  1590. X
  1591. X    if (debug > 7)
  1592. X    printf("Get-Data waitfor %s\n", (waitfor == WAIT_ACK) ? "WAIT_ACK" : "WAIT_DATA");
  1593. X    if (waitfor == WAIT_ACK)
  1594. X    timeout = 5;
  1595. X    else if (waitfor == WAIT_DATA)
  1596. X    timeout = 20;
  1597. X    else
  1598. X    timeout = 20;
  1599. X
  1600. X    for (;;) {
  1601. X    if (RxNotAcked) {                   /*  good, send ack for rx'd pkt */
  1602. X        WriteCtlPacket(CC_RR | RxSeq);
  1603. X        RxNotAcked = 0;
  1604. X    }                    /*    bad, timeout on read        */
  1605. X    if (ReadPacket(&P, (drainmode) ? 0 : timeout) == FAIL) {
  1606. X        drainmode = 0;
  1607. X
  1608. X        /*
  1609. X         *    If we have timed out waiting for data then send a reject
  1610. X         */
  1611. X
  1612. X        if (waitfor == WAIT_DATA) {
  1613. X        if (RxRetry) {
  1614. X            --RxRetry;
  1615. X            if (debug > 7)
  1616. X            printf("\nWAIT-DATA, TIMEOUT, SEND RJ\n");
  1617. X            WriteCtlPacket(CC_RJ | RxSeq);
  1618. X            continue;
  1619. X        }
  1620. X        }
  1621. X
  1622. X        /*
  1623. X         *    If we have timed out waiting for an ack send the entire
  1624. X         *    window.  We must send the window sometime and it might as
  1625. X         *    well be now.
  1626. X         */
  1627. X
  1628. X        if (waitfor == WAIT_ACK) {
  1629. X        if (RxRetry) {
  1630. X            int i;
  1631. X
  1632. X            if (debug > 7)
  1633. X            printf("RESEND %d packets\n", TxPend);
  1634. X            for (i = 1; i <= TxPend; ++i) {
  1635. X            Packet *p = &TxPacket[(TxSeq - TxPend + i) & 7];
  1636. X            p->CSeq = RxSeq;
  1637. X            WritePacket(p, 1);
  1638. X            }
  1639. X            --RxRetry;
  1640. X            continue;
  1641. X        }
  1642. X        }
  1643. X        if (debug > 7)
  1644. X        printf("COMPLETE FAILURE RxRetry = %d\n", RxRetry);
  1645. X        return(FAIL);
  1646. X    }
  1647. X
  1648. X    /*
  1649. X     *  valid packet, terminating condition?
  1650. X     */
  1651. X
  1652. X    RxRetry = 8;
  1653. X    switch(P.CType) {
  1654. X    case CT_CONTROL:
  1655. X        switch(P.CCmd) {
  1656. X        case CC_CLOSE:  /*    End of communication ... not an ACK!       */
  1657. X        if (waitfor == WAIT_CONTROL) {
  1658. X            *p = P;
  1659. X            return(SUCCESS);
  1660. X        }
  1661. X        return(FAIL);
  1662. X        case CC_RJ:     /*    Reject packet (P.CSeq == last good packet) */
  1663. X        (void)RecvdAck(P.CSeq);
  1664. X        drainmode = 1;
  1665. X        break;
  1666. X        case CC_SRJ:    /*    Selective Reject (P.CSeq == bad packet # ) */
  1667. X        return(FAIL);
  1668. X        case CC_RR:     /*    Ack to packet  (P.CSeq == packet # acked)   */
  1669. X#ifdef NOTDEF
  1670. X        if (P.CSeq == ((TxSeq - TxPend) & 7)) {
  1671. X            /*
  1672. X             * The CSeq packet was previously acknowledged
  1673. X             * The receiver apparently has not seen anything since.
  1674. X             * This is the same as a rejection.
  1675. X             */
  1676. X            goto resend;
  1677. X        }
  1678. X#endif
  1679. X        if (RecvdAck(P.CSeq) == SUCCESS && waitfor == WAIT_ACK)
  1680. X            return(SUCCESS);
  1681. X        break;
  1682. X        case CC_INITC:
  1683. X        case CC_INITB:
  1684. X        case CC_INITA:
  1685. X        if (waitfor == WAIT_CONTROL) {
  1686. X            *p = P;
  1687. X            return(SUCCESS);
  1688. X        }
  1689. X        return(FAIL);
  1690. X        }
  1691. X        break;
  1692. X    case CT_ALTCHN:
  1693. X        printf("ALTCHN packet ??\n");
  1694. X        break;
  1695. X    case CT_LONGDATA:
  1696. X    case CT_SHORTDATA:
  1697. X        {
  1698. X        char rxseq = P.CCmd >> 3;
  1699. X        char txack = P.CSeq;
  1700. X
  1701. X        if (RxRdy == 1) {
  1702. X            printf("Got two receive packets without me acking!\n");
  1703. X        }
  1704. X
  1705. X        if (rxseq == RxSeq) {   /*  already got this packet */
  1706. X            RxNotAcked = 1;
  1707. X            continue;
  1708. X                    /*  expected packet?        */
  1709. X        } else if (rxseq != ((RxSeq + 1) & 7)) {
  1710. X            drainmode = 1;
  1711. X            printf("Received sequence %d, expected %d\n", rxseq, (RxSeq + 1) & 7);
  1712. X            break;
  1713. X        }
  1714. X        if (debug > 6)
  1715. X            printf("RECV SEQUENCE %d\n", rxseq);
  1716. X
  1717. X        RecvdAck(txack);    /*  woa */
  1718. X
  1719. X        /*
  1720. X         *  Delay sending the ACK back in case we can combine
  1721. X         *  it with the next transmitted packet.
  1722. X         */
  1723. X
  1724. X        RxNotAcked = 1;     /*  we haven't ack'd the rx packet */
  1725. X
  1726. X        RxSeq = (RxSeq + 1) & 7;
  1727. X        RxRdy = 1;
  1728. X        RxPacket = P;
  1729. X        if (waitfor == WAIT_DATA)
  1730. X            return(SUCCESS);
  1731. X        if (TxPend == 0 && waitfor == WAIT_ACK)
  1732. X            return(SUCCESS);
  1733. X        }
  1734. X        break;
  1735. X    }
  1736. X    }
  1737. X}
  1738. X
  1739. XLocal
  1740. Xint
  1741. XRecvdAck(seq)
  1742. Xchar seq;
  1743. X{
  1744. X    short i;
  1745. X
  1746. X    /*
  1747. X     *    which packet was acked?
  1748. X     */
  1749. X
  1750. X    for (i = 0; i < TxPend; ++i) {
  1751. X    if (seq == ((TxSeq - i) & 7))
  1752. X        break;
  1753. X    }
  1754. X    if (i && i == TxPend) {
  1755. X    if (seq != ((TxSeq - TxPend) & 7))
  1756. X        printf("He acked the wrong packet! %d expected %d\n", seq, TxSeq);
  1757. X    return(FAIL);
  1758. X    }
  1759. X    if (debug > 7)
  1760. X    printf("TxPend %d -> %d\n", TxPend, i);
  1761. X    TxPend = i;
  1762. X    return(SUCCESS);
  1763. X}
  1764. X
  1765. XLocal
  1766. Xint
  1767. XWriteCtlPacket(cc)
  1768. Xint cc;
  1769. X{
  1770. X    Packet pk;
  1771. X
  1772. X    pk.CType = CT_CONTROL;
  1773. X    pk.CCmd  = cc & CC_MASK;
  1774. X    pk.CSeq  = cc & SEQ_MASK;
  1775. X    pk.PLen  = 0;
  1776. X    pk.DLen  = 0;
  1777. X    WritePacket(&pk, 0);
  1778. X    return(SUCCESS);
  1779. X}
  1780. X
  1781. XLocal
  1782. Xint
  1783. XWritePacket(pk, async)
  1784. XPacket *pk;
  1785. Xint async;
  1786. X{
  1787. X    Frame   F;
  1788. X    uword   sum;
  1789. X
  1790. X    F.Dle = DLE;
  1791. X    F.C   = pk->CType | pk->CCmd | pk->CSeq;
  1792. X    F.K   = 9;
  1793. X
  1794. X    if (pk->CType == CT_SHORTDATA || pk->CType == CT_LONGDATA)
  1795. X    F.K = LenToK(pk->DLen);
  1796. X    else
  1797. X    pk->DLen = 0;
  1798. X
  1799. X    sum = MAGIC - (CheckSum(pk->Data - pk->PLen, pk->DLen) ^ F.C);
  1800. X
  1801. X    F.CH  = sum >> 8;
  1802. X    F.CL  = sum;
  1803. X    F.X   = F.K ^ F.CH ^ F.CL ^ F.C;
  1804. X
  1805. X    if (debug > 7)
  1806. X    printf("WritePacket: F.K = %d F.C = %d.%d.%d\n", F.K, F.C >> 6, (F.C >> 3) & 7, F.C & 7);
  1807. X
  1808. X    if (async)
  1809. X    xwritea(&F, sizeof(F));
  1810. X    else
  1811. X    xwrite(&F, sizeof(F));      /*  write header    */
  1812. X    if (pk->DLen) {             /*  write data      */
  1813. X    if (async)
  1814. X        xwritea(pk->Data - pk->PLen, pk->DLen);
  1815. X    else
  1816. X        xwrite(pk->Data - pk->PLen, pk->DLen);
  1817. X    }
  1818. X    return(SUCCESS);
  1819. X}
  1820. X
  1821. XLocal
  1822. Xint
  1823. XReadPacket(pk, timeout)
  1824. XPacket *pk;
  1825. Xint timeout;
  1826. X{
  1827. X    Frame   F;
  1828. X    short   c;
  1829. X    short   i = 0;
  1830. X
  1831. X    pk->Data = RxBuf;
  1832. X    pk->CType = 0xFF;
  1833. X    pk->CCmd  = 0;
  1834. X    pk->CSeq  = 0;
  1835. X
  1836. X    if (debug > 7)
  1837. X    printf("ReadPacket\n");
  1838. X    while ((c = xgetc(timeout)) != EOF) {
  1839. X    if (debug > 8)
  1840. X        printf("RP %d %02x\n", i, c);
  1841. X
  1842. X    switch(i) {
  1843. X    case 0:
  1844. X        if (c == DLE) {
  1845. X        F.Dle = c;
  1846. X        ++i;
  1847. X        if (timeout == 0)
  1848. X            timeout = 1;
  1849. X        }
  1850. X        break;
  1851. X    case 1:
  1852. X        F.K = c;
  1853. X        ++i;
  1854. X        if (c == DLE) { /*  K only valid 1-9    */
  1855. X        F.Dle = c;
  1856. X        i = 1;
  1857. X        }
  1858. X        else if (c == 0 || c > 9)
  1859. X        i = 0;
  1860. X        break;
  1861. X    case 2:
  1862. X        F.CL = c;
  1863. X        ++i;
  1864. X        break;
  1865. X    case 3:
  1866. X        F.CH = c;
  1867. X        ++i;
  1868. X        break;
  1869. X    case 4:
  1870. X        F.C = c;
  1871. X        ++i;
  1872. X        break;
  1873. X    case 5:
  1874. X        F.X = c;
  1875. X        if (F.X != (F.K ^ F.CH ^ F.CL ^ F.C)) {
  1876. X        printf("F.X failed: %02x %02x\n", F.X, (F.K ^ F.CH ^ F.CL ^ F.C));
  1877. X        i = 0;
  1878. X        } else {        /*    get data segment if any */
  1879. X        ++i;
  1880. X        }
  1881. X        break;
  1882. X    }
  1883. X    if (i == 6)
  1884. X        break;
  1885. X    }
  1886. X    if (debug > 7) {
  1887. X    if (i)
  1888. X        printf("RP Hdr i = %d, F.K = %d F.C = %d.%d.%d\n", i, F.K, F.C >> 6, (F.C >> 3) & 7, F.C & 7);
  1889. X    else
  1890. X        printf("RP Hdr <rx timeout>\n");
  1891. X    }
  1892. X
  1893. X    if (i == 6) {       /*  Receive Data Portion    */
  1894. X    uword pktsize = 1 << (F.K + 4);
  1895. X    uword n;
  1896. X
  1897. X    if (F.K == 9)
  1898. X        pktsize = 0;
  1899. X
  1900. X    if (pktsize > MaxPktSize) {
  1901. X        printf("Protocol failure pktsize %d/%d/%d\n", pktsize, TxSegSize, MaxPktSize);
  1902. X        return (FAIL);
  1903. X    }
  1904. X    for (n = 0; n < pktsize; ++n) {
  1905. X        if ((c = xgetc(4)) == EOF)
  1906. X        break;
  1907. X        pk->Data[n] = c;
  1908. X    }
  1909. X    if (c != EOF) {
  1910. X        uword hissum;
  1911. X        uword oursum;
  1912. X        hissum = (F.CH << 8) | F.CL;
  1913. X        oursum = MAGIC - (CheckSum(pk->Data, pktsize) ^ F.C);
  1914. X        if (debug > 7)
  1915. X        printf("Got Data, checking: %04x %04x\n", hissum, oursum);
  1916. X        if (hissum == oursum) {
  1917. X        FrameToPacket(&F, pk, pk->Data);
  1918. X        return (SUCCESS);
  1919. X        }
  1920. X    } else {
  1921. X        FrameToPacket(&F, pk, pk->Data);    /* mainly for pk->CType */
  1922. X        return (FAIL);
  1923. X    }
  1924. X    }
  1925. X    /*
  1926. X     *    Timeout, retry?
  1927. X     */
  1928. X    return (FAIL);
  1929. X}
  1930. X
  1931. XLocal
  1932. Xint
  1933. XCheckSum(s, n)
  1934. Xubyte *s;
  1935. Xint n;
  1936. X{
  1937. X    uword sum;
  1938. X    uword x;
  1939. X    uword t;
  1940. X
  1941. X    if (n == 0)
  1942. X    return(0);
  1943. X    sum = -1;
  1944. X    x = 0;
  1945. X
  1946. X    while (n) {
  1947. X    if (sum & 0x8000)
  1948. X        sum = (sum << 1) | 1;
  1949. X    else
  1950. X        sum = (sum << 1);
  1951. X
  1952. X    t = sum;
  1953. X    sum += *s++;
  1954. X    x += sum ^ n;
  1955. X    if (sum <= t)
  1956. X        sum ^= x;
  1957. X    --n;
  1958. X    }
  1959. X    return((int)sum);
  1960. X}
  1961. X
  1962. XLocal
  1963. Xvoid
  1964. XFrameToPacket(fr, pk, data)
  1965. XFrame *fr;
  1966. XPacket *pk;
  1967. Xubyte *data;
  1968. X{
  1969. X    pk->CType = fr->C & CT_MASK;
  1970. X    pk->CCmd  = fr->C & CC_MASK;
  1971. X    pk->CSeq  = fr->C & SEQ_MASK;
  1972. X    switch(pk->CType) {
  1973. X    case CT_LONGDATA:
  1974. X    pk->DLen = 1 << (fr->K + 4);
  1975. X    break;
  1976. X    case CT_SHORTDATA:
  1977. X    pk->DLen = 1 << (fr->K + 4);
  1978. X    if (pk->Data[0] & 0x80) {
  1979. X        pk->DLen -= (pk->Data[0] & 0x7F) | (pk->Data[1] << 7);
  1980. X        if (pk->DLen < 0) {
  1981. X        printf("DLEN ERROR %d\n", pk->DLen);
  1982. X        pk->DLen = 0;
  1983. X        }
  1984. X        pk->Data += 2;
  1985. X    } else {
  1986. X        pk->DLen -= *pk->Data;
  1987. X        ++pk->Data;
  1988. X    }
  1989. X    break;
  1990. X    default:
  1991. X    pk->DLen = 0;
  1992. X    break;
  1993. X    }
  1994. X}
  1995. X
  1996. XLocal
  1997. Xint
  1998. XLenToK(bytes)
  1999. Xuword bytes;
  2000. X{
  2001. X    uword n = 32;
  2002. X    uword k = 1;
  2003. X
  2004. X    while (n < bytes) {
  2005. X    n <<= 1;
  2006. X    ++k;
  2007. X    }
  2008. X    if (k > 8) {
  2009. X    printf("Soft error, LenToK: %d %d %d\n", bytes, n, k);
  2010. X    k = 8;
  2011. X    }
  2012. X    return((int)k);
  2013. X}
  2014. X
  2015. END_OF_FILE
  2016. if test 18871 -ne `wc -c <'uucp2/src/uucico/gio.c'`; then
  2017.     echo shar: \"'uucp2/src/uucico/gio.c'\" unpacked with wrong size!
  2018. fi
  2019. # end of 'uucp2/src/uucico/gio.c'
  2020. fi
  2021. echo shar: End of archive 8 \(of 12\).
  2022. cp /dev/null ark8isdone
  2023. MISSING=""
  2024. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  2025.     if test ! -f ark${I}isdone ; then
  2026.     MISSING="${MISSING} ${I}"
  2027.     fi
  2028. done
  2029. if test "${MISSING}" = "" ; then
  2030.     echo You have unpacked all 12 archives.
  2031.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2032. else
  2033.     echo You still need to unpack the following archives:
  2034.     echo "        " ${MISSING}
  2035. fi
  2036. ##  End of shell archive.
  2037. exit 0
  2038. -- 
  2039. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  2040. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  2041. Post requests for sources, and general discussion to comp.sys.amiga.
  2042.